package entity

import (
	"sync"
)

// 支持回调的接口
type IDelayCall interface {
	//在帧尾回调这个函数，当前立即返回
	CallDelay(f CallDelayF)
	//在帧尾回调这个函数，当前协程会卡住
	CallDelayWait(f CallDelayF)
	//调用存储的函数
	Exec()
}

// 回调函数
type CallDelayF = func()

/*
用于回调函数的结构
*/
type DelayCallHost struct {
	flist []CallDelayF //需要回调的函数
	lock  sync.Mutex   //锁
}

func (this *DelayCallHost) CallDelay(f CallDelayF) {
	this.addTask(f)
}

// 加上等待
func (this *DelayCallHost) CallDelayWait(f CallDelayF) {
	gp := new(sync.WaitGroup)
	gp.Add(1)
	this.CallDelay(func() {
		defer gp.Done()
		f()
	})
	gp.Wait()
}

// 调用函数
func (this *DelayCallHost) Exec() {
	li := this.getTasks()
	for _, f := range li {
		f()
	}
}

func (this *DelayCallHost) addTask(f CallDelayF) {
	this.lock.Lock()
	defer this.lock.Unlock()
	this.flist = append(this.flist, f)
}

func (this *DelayCallHost) getTasks() (result []CallDelayF) {
	this.lock.Lock()
	defer this.lock.Unlock()
	if len(this.flist) == 0 {
		return
	}
	result = this.flist
	this.flist = make([]CallDelayF, 0, 8)
	return
}
